package org.springblade.common.config;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.modules.monitor.entity.Application;
import org.springblade.modules.monitor.mapper.ApplicationMapper;
import org.springblade.modules.monitor.service.IApplicationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


/**
 * @ClassName ApplicationTask
 * @Description
 * @Author zhang_xfei
 * @DATE 2020 2020/8/17 15:30
 **/
@Component // 此注解必加
@EnableScheduling // 此注解必加
public class ApplicationTask {

	@Autowired
	private ApplicationMapper applicationMapper;

	@Autowired
	private IApplicationService applicationService;

	private static final Logger LOGGER =  LoggerFactory.getLogger(ApplicationTask.class);
	public synchronized String  applicationSocketScan(){
		//轮询数据库中状态为0的数据
		List<Application> applications = applicationMapper.selectList(null);
		if(CollectionUtils.isEmpty(applications)){
			return null;

		}else {
			ExecutorService executorService = Executors.newFixedThreadPool(applications.size());
			List<Future<Map<String,Object>>> list = new ArrayList<>();
			for (Application application : applications) {
				Future<Map<String,Object>> socketResult = executorService.submit(() -> {
					Socket socket = new Socket();
					Map<String, Object> map = new HashMap<>();
					Integer futureValue;
					try {
						socket.connect(new InetSocketAddress(application.getIp(), application.getPort()), 3000);
						socket.close();
						if(application.getStatus().equals(0)){
							LOGGER.info("请注意："+application.getIp()+":"+application.getPort()+"之前为异常状态,现socket连接成功,修改其结果设为正常状态");
						}
						futureValue = 1;
					} catch (SocketTimeoutException se) {
						LOGGER.error("请注意："+application.getIp()+":"+application.getPort()+"连接超时,将其结果设为异常状态",se.getMessage());
						futureValue = 0;
					} catch (IOException e) {
						LOGGER.error("请注意："+application.getIp()+":"+application.getPort()+"连接（或关闭）时，IO异常,将其结果设为异常状态",e.getMessage());
						futureValue = 0;
					}
					map.put("id", application.getId());
					map.put("futureValue", futureValue);
					return map;
				});
				list.add(socketResult);
			}

			List<Application> tempApplications = new ArrayList<>();
			list.forEach(x->{
				try {
					Map<String, Object> futureValueMap = x.get();
					Application tempApplication = new Application();
					tempApplication.setId(Integer.valueOf(futureValueMap.get("id").toString()));
					tempApplication.setStatus(Integer.valueOf(futureValueMap.get("futureValue").toString()));
					tempApplications.add(tempApplication);
				} catch (InterruptedException e) {
					e.printStackTrace();
				} catch (ExecutionException e) {
					e.printStackTrace();
				}
			});
			applicationService.batchUpdateStatus(tempApplications,applications);
			//关闭 executorService
			executorService.shutdown();
		}

		return "SUCCESS";
	}

}
